#include "SysState.h"
using namespace std;


//helper function to generate random values
double randomize();


SysState::SysState(int n, int m, double lambda, int exe_round) {

	//probability of each individual Qij being select
	double prob = 2.0 * m/(n*(n-1));
	// Default Lambda value.
	default_lambda = lambda;	
	double default_l = default_lambda;
	// Default tn value.
	double default_tn = 0.5/((m+n)*default_l);

	//initialization of variables
	this->n=n;
	Ts = new double[n];

	B = new int*[n];
	L = new double*[n];
	Tn = new double*[n];
	q_cum = new double*[n];
	q_max = new double*[n];
	q_count = new int*[n];
	for (int i = 0; i < n; ++i) {
		B[i] = new int[n];
		L[i] = new double[n];
		Tn[i] = new double[n];
		q_cum[i] = new double[n];
		q_max[i] = new double[n];
		q_count[i] = new int[n];
		//initialize variable
		memset(q_count[i], 0, sizeof(int)*n);
	
		for(int j=0; j<n; j++){
			q_cum[i][j] = 0;
			q_max[i][j] = 0;
			L[i][j] = 0;
			B[i][j] = 0;
			Tn[i][j] = 0;
		}	
		//generate values for lamda and tn for each queue
		for(int j = i+1; j<n; ++j){
			if((double)rand()/RAND_MAX < prob){
				L[i][j] = default_l * randomize();
				Tn[i][j] = default_tn * randomize();
			}	
		}
		L[i][i] = default_l * randomize();
		Tn[i][i] = default_tn * randomize();

		//random generate ts values
		//a bit of hard code
		double randnum = (double)rand() / RAND_MAX;
		if( randnum < 0.4){
			Ts[i] = 10*default_tn;
		}else if( randnum < 0.8){
			Ts[i] = 15*default_tn;
		}else{
			Ts[i] = 20*default_tn;
		}
	}

	max_time = 0;
	cum_time = 0;
	total_done_job = 0;
	
	this->exe_round = exe_round;
	pwt_queue = new double[exe_round]();
	maxpwt_queue = new double[exe_round]();
}

void SysState::reset(int n, int m){
	//probability of each individual Qij being select
	double prob = 2.0 * m/(n*(n-1));
	// Default lambda value. 
	double default_l = default_lambda;
	// Default tn value.
	double default_tn = 0.5/((m+n)*default_l);

	for(int i=0; i<n; ++i){
		for(int j=0; j<n; ++j){
			B[i][j] = 0;
			q_cum[i][j] = 0;
			q_max[i][j] = 0;
			q_count[i][j] = 0;
		}
	}

	for(int i=0; i<n; ++i){
		for(int j=i+1; j<n; ++j){
			if((double)rand()/RAND_MAX < prob){
				L[i][j] = default_l * randomize();
				Tn[i][j] = default_tn * randomize();
			}	
		}
		L[i][i] = default_l * randomize();
		Tn[i][i] = default_tn * randomize();

		//random generate ts values
		//a bit of hard code
		double randnum = (double)rand() / RAND_MAX;
		// double randnum = 0.6;
		if( randnum < 0.4){
			Ts[i] = 10*default_tn;
		}else if( randnum < 0.8){
			Ts[i] = 15*default_tn;
		}else{
			Ts[i] = 20*default_tn;
		}

	}


	max_time = 0;
	cum_time = 0;
	total_done_job = 0;
}

SysState::~SysState(){
	for (int i = 0; i < n; ++i){
		delete B[i];
		delete L[i];
		delete Tn[i];
		delete q_cum[i];
		delete q_max[i];
		delete q_count[i];
	}
	delete B;
	delete L;
	delete Tn;
	delete q_cum;
	delete q_max;
	delete q_count;
	delete Ts;
	delete pwt_queue;
	delete maxpwt_queue;
}

double randomize(){
	double randnum = (double) rand()/RAND_MAX;
	if(randnum < 0.3){
		return 1;
	}
	else if(randnum < 0.6){
		return 0.85;
	}else{
		return 0.7;
	}
}
